package com.kws.merchant.config;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kws.merchant.domain.Contract;
import com.kws.merchant.domain.Device;
import com.kws.merchant.domain.Order;
import com.kws.merchant.service.ContractService;
import com.kws.merchant.service.DeviceService;
import com.kws.merchant.service.OrderService;
import com.kws.merchant.util.RedisLockService;
import com.kws.system.api.domain.SignFlowRevoke;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * @author : zhangbenting
 * @date : 2024/12/23 10:58
 * @Version: 1.0
 */

@Slf4j
@Component
public class RedisKeyExpiredListener extends KeyExpirationEventMessageListener {

    @Autowired
    private RedisLockService redisLockService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private ContractService contractService;


    public RedisKeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] bytes) {
        //获取失效key名称
        String expireKey = new String(message.getBody(), StandardCharsets.UTF_8);
        if (expireKey.contains("order:")) {
            String idStr = IdWorker.getIdStr();
            String lockKey = "order_lock:" + idStr;
            String lockValue = idStr;
            try {
                // 尝试获取锁
                if (redisLockService.acquireLock(lockKey, lockValue, 8000)) {
                    //商户支付订单id
                    String orderId = expireKey.replace("order:", "");
                    Order orderEntity = orderService.getById(orderId);
                    if (ObjectUtil.isNotEmpty(orderEntity)) {
                        //todo 调用第三方接口查询订单是否已经支付成功
                        //查询是否未超时未支付的状态
                        if (orderEntity.getStatus()==1) {
                            return;
                        } else {
                            orderEntity.setStatus(5);
                            orderEntity.setUpdateTime(new Date());
                            if (orderEntity.getType().equals(0)) {
                                //设备订单，设备返回库存
                                Device deviceById = deviceService.getById(orderEntity.getGoodsId());
                                deviceById.setInventory(deviceById.getInventory() + orderEntity.getGoodsCount());
                                deviceService.saveOrUpdate(deviceById);
                                System.out.println("商品设备返回库存成功");

                            }
                            //合同作废
                            LambdaQueryWrapper<Contract> wrapper = Wrappers.lambdaQuery();
                            wrapper.eq(Contract::getOrderId, orderId);
                            Contract contractEntity = contractService.getOne(wrapper);
                            if (ObjectUtils.isNotNull(contractEntity)){
                                SignFlowRevoke signFlowRevoke = new SignFlowRevoke();
                                signFlowRevoke.setSignFlowId(contractEntity.getSignFlowId());
                                signFlowRevoke.setRevokeReason("取消签订");
                                contractService.signFlowRevoke(signFlowRevoke);
                            }
                            orderService.updateById(orderEntity);
                        }
                    }
                } else {
                    log.info("获取锁失败或已被其他服务处理！");
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e.getMessage());
            } finally {
                redisLockService.releaseLock(lockKey, lockValue);
            }
        }
    }
}
